﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EntityDataModel;

namespace DataAccessLayer
{
    public class UserDAL
    {
        /// <summary>     
        /// Get all users from the database.
        /// </summary>
        public static List<User> GetAllUsers()
        {
            using (liveCPEEntities context = new liveCPEEntities())
            {
                try
                {
                    List<User> users = context.Users.ToList();
                    return users;
                }
                catch (Exception e)
                {
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                    LogDAL.AddLog(e.Message, "Error", DataAccessLayerSettings.Default.ApplicationName, sf.GetMethod().Name, DateTime.Now);
                    throw new Exception(sf.GetMethod().Name + " unexpected error", e);
                }
            }
        }

        /// <summary>     
        /// Create an user in the database.
        /// </summary>
        public static void CreateUser(String userName, string firstName, string lastName, bool gender, DateTime? dateOfBirth, DateTime subscriptionDate)
        {
            using (liveCPEEntities context = new liveCPEEntities())
            {
                try
                {
                    context.Users.AddObject(new User
                    {
                        UserName = userName,
                        FirstName = firstName,
                        LastName = lastName,
                        Gender = gender,
                        DateOfBirth = dateOfBirth,
                        SubscriptionDate = subscriptionDate,
                        NumFriends = 0
                    });

                    context.SaveChanges();
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                    LogDAL.AddLog("User creation : " + firstName + " " + lastName, "Info", DataAccessLayerSettings.Default.ApplicationName, sf.GetMethod().Name, DateTime.Now);
                }
                catch (Exception e)
                {
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                    LogDAL.AddLog(e.Message, "Error", DataAccessLayerSettings.Default.ApplicationName, sf.GetMethod().Name, DateTime.Now);
                    throw new Exception(sf.GetMethod().Name + " unexpected error", e);
                }
            }
        }

        /// <summary>     
        /// Update an user in the database.
        /// </summary>
        public static void UpdateUser(String userName, string firstName, string lastName, bool gender, DateTime? dateOfBirth, String email, DateTime subscriptionDate)
        {
            using (liveCPEEntities context = new liveCPEEntities())
            {
                try
                {
                    User user = context.Users.First(u => u.UserName == userName);
                    user.UserName = userName;
                    user.FirstName = firstName;
                    user.LastName = lastName;
                    user.Gender = gender;
                    user.DateOfBirth = dateOfBirth;
                    user.SubscriptionDate = subscriptionDate;
                    user.NumFriends = 0;

                    aspnet_Users aspUser = context.aspnet_Users.First(u => u.UserName == userName);
                    aspUser.aspnet_Membership.Email = email;
                    aspUser.aspnet_Membership.LoweredEmail = email.ToLower();

                    context.SaveChanges();
                }
                catch (Exception e)
                {
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                    LogDAL.AddLog(e.Message, "Error", DataAccessLayerSettings.Default.ApplicationName, sf.GetMethod().Name, DateTime.Now);
                    throw new Exception(sf.GetMethod().Name + " unexpected error", e);
                }
            }
        }

        /// <summary>     
        /// Update user's picture
        /// </summary>
        public static void UpdatePictureForUser(String userName, byte[] picture)
        {
            using (liveCPEEntities context = new liveCPEEntities())
            {
                try
                {
                    User user = context.Users.First(u => u.UserName == userName);
                    user.Picture = picture;

                    context.SaveChanges();
                }
                catch (Exception e)
                {
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                    LogDAL.AddLog(e.Message, "Error", DataAccessLayerSettings.Default.ApplicationName, sf.GetMethod().Name, DateTime.Now);
                    throw new Exception(sf.GetMethod().Name + " unexpected error", e);
                }
            }
        }

        /// <summary>     
        /// Get user's picture
        /// </summary>
        public static byte[] GetPictureForUser(String userName)
        {
            using (liveCPEEntities context = new liveCPEEntities())
            {
                try
                {
                    List<User> users = (from u in context.Users where u.UserName.ToLower() == userName.ToLower() select u).ToList();
                    if (users.Count != 1)
                    {
                        return context.Users.First(u => u.UserName == "default").Picture;
                    }
                    return users.First().Picture;
                }
                catch (Exception e)
                {
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                    LogDAL.AddLog(e.Message, "Error", DataAccessLayerSettings.Default.ApplicationName, sf.GetMethod().Name, DateTime.Now);
                    throw new Exception(sf.GetMethod().Name + " unexpected error", e);
                }
            }
        }

        /// <summary>     
        /// Get user by username
        /// </summary>
        public static User GetUserByUserName(string userName)
        {
            using (liveCPEEntities context = new liveCPEEntities())
            {
                try
                {
                    IQueryable<User> user = from u in context.Users where u.UserName == userName select u;
                    List<User> users = user.ToList();
                    if (users.Count == 1)
                    {
                        return user.First();
                    }
                    else
                    {
                        return null;
                    }
                }
                catch (Exception e)
                {
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                    LogDAL.AddLog(e.Message, "Error", DataAccessLayerSettings.Default.ApplicationName, sf.GetMethod().Name, DateTime.Now);
                    throw new Exception(sf.GetMethod().Name + " unexpected error", e);
                }
            }
        }

        /// <summary>     
        /// Get mail for user
        /// </summary>
        public static String GetEmail(string userName)
        {
            using (liveCPEEntities context = new liveCPEEntities())
            {
                try
                {
                    return context.aspnet_Users.First(u => u.UserName == userName).aspnet_Membership.Email;
                }
                catch (Exception e)
                {
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                    LogDAL.AddLog(e.Message, "Error", DataAccessLayerSettings.Default.ApplicationName, sf.GetMethod().Name, DateTime.Now);
                    throw new Exception(sf.GetMethod().Name + " unexpected error", e);
                }
            }
        }

        /// <summary>     
        /// Get all users names from the table User
        /// </summary>
        public static String[] GetAllUserNames()
        {
            using (liveCPEEntities context = new liveCPEEntities())
            {
                try
                {
                    IQueryable<String> listUser = from u in context.Users orderby u.UserName ascending select u.UserName.TrimEnd();
                    return listUser.ToArray();
                }
                catch (Exception e)
                {
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                    LogDAL.AddLog(e.Message, "Error", DataAccessLayerSettings.Default.ApplicationName, sf.GetMethod().Name, DateTime.Now);
                    throw new Exception(sf.GetMethod().Name + " unexpected error", e);
                }
            }
        }

        /// <summary>     
        /// Return true if the given user exists in the table User
        /// </summary>
        public static Boolean IsUser(User user)
        {
            using (liveCPEEntities context = new liveCPEEntities())
            {
                try
                {
                    return (from u in context.Users where u.UserName == user.UserName select u).Any();
                }
                catch (Exception e)
                {
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                    LogDAL.AddLog(e.Message, "Error", DataAccessLayerSettings.Default.ApplicationName, sf.GetMethod().Name, DateTime.Now);
                    throw new Exception(sf.GetMethod().Name + " unexpected error", e);
                }
            }
        }

        /// <summary>     
        /// Return true if the given user exists in the table User
        /// </summary>
        public static Boolean IsUser(String userName)
        {
            using (liveCPEEntities context = new liveCPEEntities())
            {
                try
                {
                    return (from u in context.Users where u.UserName == userName select u).Any();
                }
                catch (Exception e)
                {
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                    LogDAL.AddLog(e.Message, "Error", DataAccessLayerSettings.Default.ApplicationName, sf.GetMethod().Name, DateTime.Now);
                    throw new Exception(sf.GetMethod().Name + " unexpected error", e);
                }
            }
        }
    }
}
